package com.common.code;




import com.common.entity.MessageType;
import com.common.entity.RPCRequest;
import com.common.entity.RPCResponse;
import com.common.serialize.CommonSerializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Zixiang Hu
 * @description 自定义netty的编码器，在进行通信时无非发送公用请求或者响应
 * @create 2021-02-28-16:17
 */
@AllArgsConstructor
@Builder
@Slf4j
public class MyNettyEncoder extends MessageToByteEncoder {
    // 定义序列化规则
    private CommonSerializer serializer;

    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
        // 如果msg的类型是响应，则先发送一个响应代表的整形数据;否者发送请求代表的code
        if (msg instanceof RPCResponse) {
            out.writeInt(MessageType.RESPONSE.getCode());
        } else if (msg instanceof RPCRequest) {
            out.writeInt(MessageType.REQUEST.getCode());
        } else {
            log.error("待编码的msg类型不符合要求");
            return;
        }
        // 发送序列化code，以便解码器能使用对应的反序列化
        out.writeInt(serializer.getCode());
        byte[] content = serializer.serialize(msg);
        // 写入字节长度，避免粘包问题
        out.writeInt(content.length);
        out.writeBytes(content);
    }
}
